<?php

/**
 * uniBoard Users Helper Functions
 *
 * Light and fast forum solution for web 2.0-like communities.
 *
 * @package		uniBoard
 * @author		Rafał Pitoń
 * @license		http://www.gnu.org/licenses/gpl-3.0.html
 * @since		Version 0.1
 * 
 * ------------------------------------------------------------------------
 * 
 * $Date: 2010-09-20 21:23:27 +0000 (Mon, 20 Sep 2010) $
 * $Revision: 64 $
 * $Author: rafio.xudb@gmail.com $
 */

// ------------------------------------------------------------------------

class class_users{
		
	/**
	 * Main class pointer
	 *
	 * @var object
	 */
	
	private $appCore			= NULL;
	
	/**
	 * Disallowed Names
	 *
	 * @var array
	 */
	
	private $disallow_names 	= array();
	
	/**
	 * Names Loaded?
	 *
	 * @var bool
	 */
	
	private $names_loaded	 	= false;
	
	/**
	 * Disallowed Titles
	 *
	 * @var array
	 */
	
	private $disallow_titles 	= array();
	
	/**
	 * Titles Loaded?
	 *
	 * @var bool
	 */
	
	private $titles_loaded	 	= false;
	
	// ------------------------------------------------------------------------

	/**
	 * Initialise Helper
	 *
	 * @param object $appCore
	 */
	
	function __construct( $appCore){
		
		// Store appCore pointer
		$this -> appCore = $appCore;
		
	}
	
	/**
	 * Returns User Rank
	 *
	 * @param integer $user_rank_id
	 * @param integer $group_rank_id
	 * @param integer $users_posts
	 * @return string
	 */
	
	function getRankTitle($user_rank_id, $group_rank_id, $users_posts){
		
		// Load ranks?
		if ( !isset($this -> appCore -> cache_store['user_ranks']))
		{
			// Get ranks
			$this -> getUserRanks();
		}
		
		// Check User Rank
		if ($user_rank_id > 0 && isset($this -> appCore -> cache_store['user_ranks'][$user_rank_id]))
		{
			// Return title
			return $this -> appCore -> cache_store['user_ranks'][$user_rank_id]['rank_name'];
		}
		else if ($group_rank_id > 0 && isset($this -> appCore -> cache_store['user_ranks'][$group_rank_id]))
		{
			// Return title
			return $this -> appCore -> cache_store['user_ranks'][$group_rank_id]['rank_name'];
		}
		else
		{
			// Reiterate
			foreach ( $this -> appCore -> cache_store['user_ranks'] as $rank_data)
			{
				// rank match?
				if ( !$rank_data['rank_special'] && $users_posts >= $rank_data['rank_posts'])
				{
					// Return rank
					return $rank_data['rank_name'];
				}
			}
			
			// Return null, we failed to find rank
			return NULL;
		}
		
	}
	
	/**
	 * Returns User Rank
	 *
	 * @param integer $user_rank_id
	 * @param integer $group_rank_id
	 * @param integer $users_posts
	 * @return array
	 */
	
	function getRank($user_rank_id, $group_rank_id, $users_posts){
		
		// Load ranks?
		if ( !isset($this -> appCore -> cache_store['user_ranks']))
		{
			// Get ranks
			$this -> getUserRanks();
		}
		
		// Check User Rank
		if ($user_rank_id > 0 && isset($this -> appCore -> cache_store['user_ranks'][$user_rank_id]))
		{
			// Return title
			return array(
				$this -> appCore -> cache_store['user_ranks'][$user_rank_id]['rank_name'],
				$this -> appCore -> cache_store['user_ranks'][$user_rank_id]['rank_image']
			);
		}
		else if ($group_rank_id > 0 && isset($this -> appCore -> cache_store['user_ranks'][$group_rank_id]))
		{
			// Return title
			return array(
				$this -> appCore -> cache_store['user_ranks'][$group_rank_id]['rank_name'],
				$this -> appCore -> cache_store['user_ranks'][$group_rank_id]['rank_image']
			);
		}
		else
		{
			// Reiterate
			foreach ( $this -> appCore -> cache_store['user_ranks'] as $rank_data)
			{
				// rank match?
				if ( !$rank_data['rank_special'] && $users_posts >= $rank_data['rank_posts'])
				{
					// Return rank
					return array(
						$rank_data['rank_name'],
						$rank_data['rank_image'],
					);
				}
			}
			
			// Return null, we failed to find rank
			return NULL;
		}
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Compares User Name to blacklist, returns true if name is allowed
	 *
	 * @param string $name
	 * @return bool
	 */
	
	function nameValid( $name){
		
		// Load User Names
		if ( !$this -> names_loaded)
		{
			// We Loaded Names
			$this -> names_loaded = true;
			
			// Get them from Cache
			$this -> disallow_names = class_cache::loadCache( 'disallow_names');
			
			// No Cache?
			if ( class_cache::$load_error)
			{
				// Select Them
				$this -> appCore -> db -> query( 'SELECT disallow_name FROM ' . DB_PREFIX . 'disallow_names');
				
				// Pass them to array
				while ( $dissallow_result = $this -> appCore -> db -> fetch_array())
				{
					// Name not Empty?
					if ( isset( $dissallow_result[0][0]))
					{
						$this -> disallow_names[] = mb_strtolower( $dissallow_result[0]);
					}
				}
				
				// Free Result
				$this -> appCore -> db -> freeResult();
				
				// Save Cache
				class_cache::saveCache( 'disallow_names', $this -> disallow_names);
			}
		}
		
		// Any names in black List?
		if ( isset( $this -> disallow_names[0]))
		{
			// Number of names
			$names_n = count( $this -> disallow_names);
		
			// Our String to lowercase
			$name = mb_strtolower( $name);
				
			// Loop
			for ( $i = 0; $i < $names_n; $i ++)
			{
				// Non-Regex comparision
				if ((strpos( $this -> disallow_names[$i], '*') === false && $name == $this -> disallow_names[$i]) ||  preg_match('#^' . str_replace('\*', '.*?', preg_quote($this -> disallow_names[$i], '#')) . '$#i', $name))
				{
					return false;
				}
			}
		}
		
		// Return True if we are there
		return true;
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Compares User Title to blacklist, returns true if name is allowed
	 *
	 * @param string $name
	 * @return bool
	 */
	
	function titleValid( $name){
		
		// Load User Titles
		if ( !$this -> titles_loaded)
		{
			// We Loaded Titles
			$this -> titles_loaded = true;
			
			// Get them from Cache
			$this -> disallow_names = class_cache::loadCache( 'disallow_titles');
			
			// No Cache?
			if ( class_cache::$load_error)
			{
				// Select Them
				$this -> appCore -> db -> query( 'SELECT disallow_title FROM ' . DB_PREFIX . 'disallow_names');
				
				// Pass them to array
				while ( $dissallow_result = $this -> appCore -> db -> fetch_array())
				{
					// Title not Empty?
					if ( isset( $dissallow_result[0][0]))
					{
						$this -> disallow_titles[] = mb_strtolower( $dissallow_result[0]);
					}
				}
				
				// Free Result
				$this -> appCore -> db -> freeResult();
				
				// Save Cache
				class_cache::saveCache( 'disallow_titles', $this -> disallow_titles);
			}
		}
		
		// Any titles in black List?
		if ( isset( $this -> disallow_titles[0]))
		{
			// Number of names
			$names_n = count( $this -> disallow_titles);
		
			// Our String to lowercase
			$name = mb_strtolower( $name);
				
			// Loop
			for ( $i = 0; $i < $names_n; $i ++)
			{
				// Non-Regex comparision
				if ( (strpos( $this -> disallow_titles[$i], '*') === false && $name == $this -> disallow_titles[$i]) ||  preg_match('#^' . str_replace('\*', '.*?', preg_quote($this -> disallow_titles[$i], '#')) . '$#i', $name))
				{
					return false;
				}
			}
		}
		
		// Return True if we are there
		return true;
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Checks user name avaiability
	 *
	 * @param string $name
	 * @return bool
	 */
	
	function nameAvaiable( $user_name, $except = 0){
		
		return ( $this -> appCore -> db -> count( 'users', 'user_name LIKE \'' . $this -> appCore -> db -> strEscape( $user_name, true) . '\' AND user_id > \'0\' AND user_id <> \'' . $except . '\' LIMIT 1') == 0);
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Checks user login avaiability
	 *
	 * @param string $name
	 * @return bool
	 */
	
	function loginAvaiable( $user_name, $except = 0){
		
		return ( $this -> appCore -> db -> count( 'users', 'user_login LIKE \'' . $this -> appCore -> db -> strEscape( $user_name, true) . '\' AND user_id > \'0\' AND user_id <> \'' . $except . '\' LIMIT 1') == 0);
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Checks user E-Mail avaiability
	 *
	 * @param string $name
	 * @return bool
	 */
	
	function emailAvaiable( $user_email, $except = 0){
		
		return ( $this -> appCore -> db -> count( 'users', 'user_email LIKE \'' . $this -> appCore -> db -> strEscape( $user_email, true) . '\' AND user_id > \'0\' AND user_id <> \'' . $except . '\' LIMIT 1') == 0);
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Sets Latest Member to new one
	 *
	 * @param integer $id
	 * @param string $name
	 * @param bool $count
	 */
	
	function setLatestUser( $id, $name, $count = true){
		
		// Update Settings
		$this -> appCore -> db -> update( array( 'setting_value' => (int) $id), 'settings', 'setting_id = \'stat_last_user\'');
		$this -> appCore -> db -> update( array( 'setting_value' => $this -> appCore -> db -> strEscape( $name)), 'settings', 'setting_id = \'stat_last_user_name\'');
		
		// Update Counter?
		if ( $count)
		{
			$this -> appCore -> db -> update( array( 'setting_value' => (1 + $this -> appCore -> conf['stat_users'])), 'settings', 'setting_id = \'stat_users\'');
		}
		
		// Kill Cache
		class_cache::flushCache( 'configuration');
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Loads User Ranks from cache
	 *
	 */
	
	function getUserRanks(){
		
		// Load User Ranks
		if ( !isset( $this -> appCore -> cache_store['user_ranks']))
		{
			// Get them from Cache
			$this -> appCore -> cache_store['user_ranks'] = class_cache::loadCache( 'user_ranks');
			
			// No Cache?
			if ( class_cache::$load_error)
			{
				// Select Them
				$this -> appCore -> db -> query( 'SELECT *
				FROM ' . DB_PREFIX . 'user_ranks
				ORDER BY rank_special, rank_posts DESC');
				
				// Pass them to array
				while ( $rank_result = $this -> appCore -> db -> fetch_assoc())
				{
					// Escape rank name
					$rank_result['rank_name'] = htmlspecialchars($rank_result['rank_name']);
					
					// Add to result
					$this -> appCore -> cache_store['user_ranks'][$rank_result['rank_id']] = $rank_result;
				}
				
				// Free Result
				$this -> appCore -> db -> freeResult();
				
				// Save Cache
				class_cache::saveCache( 'user_ranks', $this -> appCore -> cache_store['user_ranks']);
			}
			
			// Fix ranks
			foreach ( $this -> appCore -> cache_store['user_ranks'] as $rank_id => $rank_data)
			{
				// Fix rank name and image?
				if ($this -> appCore -> conf['board_int_ranks'])
				{
					// Translate name
					$rank_data['rank_name'] = $this -> appCore -> ifString($rank_data['rank_name']);
					
					// Translate image
					if (isset($rank_data['rank_image'][0]))
					{
						$rank_data['rank_image'] = str_replace('{L}', $this -> appCore -> user['language_iso'], $rank_data['rank_image']);
					}
				}
				
				// Draw Rank Image?
				if ( $rank_data['rank_stars'] > 0)
				{
					// Source Image
					if ( isset($rank_data['rank_image'][0]))
					{
						$rank_data['rank_image'] = '<img src="' . IMAGES_PATH . htmlspecialchars($rank_data['rank_image']) . '" alt="' . htmlspecialchars($rank_data['rank_name']) . '" title="' . htmlspecialchars($rank_data['rank_name']) . '" />';
					}
					else
					{
						$rank_data['rank_image'] = $this -> appCore -> output -> drawImage('pip');
					}
					
					// Loop it?
					if ($rank_data['rank_stars'] > 1 && $rank_data['rank_stars'] < 33)
					{
						$rank_data['rank_image'] = str_repeat($rank_data['rank_image'], $rank_data['rank_stars']);
					}
				}
				else
				{
					// Empty image
					$rank_data['rank_image'] = '';
				}
				
				// Update changes
				$this -> appCore -> cache_store['user_ranks'][$rank_id] = $rank_data;
			}
		}
			
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Makes user member of group
	 *
	 * @param integer $id
	 * @param string $name
	 */
	
	function makeMember( $group, $user){
		
		// Insert
		$this -> appCore -> db -> insert( array( 'group_id' => (int) $group, 'user_id' => (int) $user), 'user_groups_members');
				
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Returns list of Avaiable User Groups
	 *
	 * @param bool $rich_text
	 * @param bool $return
	 * @return array
	 */
	
	function getUserGroups( $rich_text = false, $return = true){
		
		// Load User Groups
		if ( !isset( $this -> appCore -> cache_store['user_groups']))
		{
			// Get them from Cache
			$this -> appCore -> cache_store['user_groups'] = class_cache::loadCache( 'user_groups');
			
			// No Cache?
			if ( class_cache::$load_error)
			{
				// Select Them
				$this -> appCore -> db -> query( 'SELECT group_id, group_name, group_prefix, group_suffix, group_hidden, group_rank
				FROM ' . DB_PREFIX . 'user_groups
				ORDER BY group_pos');
				
				// Pass them to array
				while ( $group_result = $this -> appCore -> db -> fetch_assoc())
				{
					$this -> appCore -> cache_store['user_groups'][$group_result['group_id']] = $group_result;
				}
				
				// Free Result
				$this -> appCore -> db -> freeResult();
				
				// Save Cache
				class_cache::saveCache( 'user_groups', $this -> appCore -> cache_store['user_groups']);
			}
			
			// Translate basterds!
			foreach ( $this -> appCore -> cache_store['user_groups'] as $group_id => $group_data)
			{
				// Set Group name
				$this -> appCore -> cache_store['user_groups'][$group_id]['group_name'] = $this -> appCore -> ifString( htmlspecialchars( $group_data['group_name']));
			}
		}
		
		// Return anything?
		if ($return)
		{
			// Ready Array
			$ready_array = array();
			
			// Return Rich Text?
			if ( $rich_text)
			{
				foreach ( $this -> appCore -> cache_store['user_groups'] as $group_id => $group_data)
				{
					$ready_array[$group_id] = $group_data['group_prefix'] . $group_data['group_name'] . $group_data['group_suffix'];
				}
			}
			else
			{
				foreach ( $this -> appCore -> cache_store['user_groups'] as $group_id => $group_data)
				{
					$ready_array[$group_id] = $group_data['group_name'];
				}
			}
			
			// Return done array
			return $ready_array;
		}
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Updates User Name across DB
	 *
	 * @param integer $user_id
	 * @param string $user_name
	 */
	
	function updateUserName( $user_id, $user_name){
		
		// Fix ID
		settype( $user_id, 'integer');
		
		// Escape String
		$user_name_clean = $this -> appCore -> db -> strEscape( $user_name);
		
		// Update Latest Member?
		if ( $user_id == $this -> appCore -> conf['stat_last_user'])
		{
			// Get him from DB
			$this -> appCore -> setConfig( 'stat_last_user_name', $user_name);
		}
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Deletes Users
	 *
	 * @param array $delete_users
	 */
	
	function deleteUsers( $delete_users){
		
		// Array with user ID\'s
		$user_ids = array_keys( $delete_users);
		
		// Delete users from DB
		$this -> appCore -> db -> delete( 'users', 'user_id IN (' . $this -> appCore -> db -> strEscape( join( ',', $user_ids)) . ')');
		$this -> appCore -> db -> delete( 'user_groups_members', 'user_id IN (' . $this -> appCore -> db -> strEscape( join( ',', $user_ids)) . ')');
		
		$this -> appCore -> db -> delete( 'sessions_keys', 'user_id IN (' . $this -> appCore -> db -> strEscape( join( ',', $user_ids)) . ')');
		$this -> appCore -> db -> delete( 'sessions_admin', 'user_id IN (' . $this -> appCore -> db -> strEscape( join( ',', $user_ids)) . ')');
		$this -> appCore -> db -> delete( 'sessions', 'user_id IN (' . $this -> appCore -> db -> strEscape( join( ',', $user_ids)) . ')');
		$this -> appCore -> db -> delete( 'ban_filters', 'user_id IN (' . $this -> appCore -> db -> strEscape( join( ',', $user_ids)) . ')');
		
		// Resynch DB
		foreach ( $delete_users as $user_id => $user_name)
		{
			// Make ID integer
			settype( $user_id, 'integer');
			
			// Escape data
			$user_name = $this -> appCore -> strEscape( $user_name);
			
			// Update Tables
			$this -> appCore -> db -> update( array( 'user_id' => -1, 'user_name' => $user_name), 'logs_admin', 'user_id = \'' . $user_id . '\'');
			$this -> appCore -> db -> update( array( 'user_id' => -1), 'logs_admin_access', 'user_id = \'' . $user_id . '\'');
		}
		
		// Update Last Member?
		if ( isset( $delete_users[$this -> appCore -> conf['stat_last_user']]))
		{
			// Grab new Latest User
			$this -> appCore -> db -> query( 'SELECT user_id, user_name FROM ' . DB_PREFIX . 'users ORDER BY user_join_date DESC LIMIT 1');
			
			// Update Config
			$user_result = $this -> appCore -> db -> fetch_array();
			$this -> setLatestUser( $user_result[0], $user_result[1], false);
			
			// Free Result
			$this -> appCore -> db -> freeResult();
		}
		
	}
	
	// ------------------------------------------------------------------------

	/**
	 * Returns Avatar Location
	 *
	 * @param integer $avatar_type
	 * @return string
	 */
	
	static function avatarLocation( $avatar_type){
		
		if ( $avatar_type == 2)
		{
			// Return Galleries
			return AVATARS_GALLERY_PATH;
		}
		else if ( $avatar_type == 3)
		{
			// Return Uploads
			return UPLOADS_PATH;
		}
		else
		{
			// Return NULL
			return '';
		}
		
	}
	
}